home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
MacPNG Library 1.02
/
pngMacSrc 1.02
/
Re- Mac Port of PNG libraries
< prev
next >
Wrap
Text File
|
1996-05-16
|
16KB
|
430 lines
Mark,
I just surfed to your Web page, not bad at all. (I'm based in
mississauga ont. BTW) With Regards to ReadPNG.c. I basically added my own
CreatePICT2 routine to use a GWorld to convert the raw pixel buffer from
the PNG image returned in row_buf. Unfortunately it isn't working, and i'm
not sure whether the stuff read into row_buf was wrong, or whether my
copying of the pixel image from the PNG buffer to the Gworld buffer is
wrong because I'm not taking into account something about the PNG image
layout. Any suggestions would be appreciated.
#include <stdio.h>
#include <stdlib.h>
#include "png.h"
// Requires: libpng, zlib, ANSI (4i) C lib's
#include <Files.h>
#include <Memory.h>
#define RECT_TOP(rect) (rect).top
#define RECT_LEFT(rect) (rect).left
#define RECT_BOTTOM(rect) (rect).bottom
#define RECT_RIGHT(rect) (rect).right
#define RECT_WIDTH(rect) (RECT_RIGHT(rect) - RECT_LEFT(rect) )
#define RECT_HEIGHT(rect) (RECT_BOTTOM(rect) - RECT_TOP(rect) )
#define RECT_MIDX(rect) (RECT_LEFT(rect) + (RECT_RIGHT(rect) - RECT_LEFT(rect) >> 1) )
#define RECT_MIDY(rect) (RECT_TOP(rect) + (RECT_BOTTOM(rect) - RECT_TOP(rect) >> 1) )
extern OSErr DumpPixMap(PixMapHandle aPixMap);
PicHandle CreatePICT2(PixMap *pixMap,Rect *boundsRect, short mode);
PicHandle ReadPGN(FSSpec *sfFilePtr);
PicHandle ReadPGN(FSSpec *sfFilePtr)
{
OSErr err = noErr;
short savedVol;
Str31 name;
png_struct read_ptr;
png_info info_ptr;
png_info end_info;
FILE *fpin;
png_byte *row_buf;
png_uint_32 rowbytes;
png_uint_32 y, x;
int channels, num_pass, pass;
PicHandle myPic = nil;
BlockMoveData((Ptr)(sfFilePtr->name), (Ptr)name, sizeof(Str31));
err = GetVol(0, &savedVol);
if (err == noErr)
{
err = HSetVol(0, sfFilePtr->vRefNum, sfFilePtr->parID);
if (err == noErr)
{
p2cstr(name);
row_buf = (png_byte *)0;
fpin = fopen((char *) name, "rb");
if (!fpin)
{
// fprintf(STDERR, "Could not find input file %s\n", inname);
return NULL;
}
if (setjmp(read_ptr.jmpbuf))
{
// fprintf(STDERR, "libpng read error\n");
fclose(fpin);
return NULL;
}
png_read_init(&read_ptr);
png_info_init(&info_ptr);
png_info_init(&end_info);
png_init_io(&read_ptr, fpin);
png_read_info(&read_ptr, &info_ptr);
#if OutputInfo /* RMF */
fprintf(STDERR, "%s, Width = %d, Height = %d, Depth = %d\n",
inname, info_ptr.width, info_ptr.height, info_ptr.bit_depth);
fprintf(STDERR, "Color type = %d, interlace_type = %d\n",
info_ptr.color_type, info_ptr.interlace_type);
#endif
if ((info_ptr.color_type & 3) == PNG_COLOR_MASK_COLOR)
channels = 3;
else channels = 1;
if (info_ptr.color_type & PNG_COLOR_MASK_ALPHA)
channels++;
rowbytes = ((info_ptr.width * info_ptr.bit_depth * channels + 7) >> 3);
// row_buf = (png_byte *)malloc((size_t)rowbytes);
row_buf = (png_byte *)NewPtrClear(rowbytes);
if (!row_buf)
{
//R4L fprintf(STDERR, "no memory to allocate row buffer\n");
png_read_destroy(&read_ptr, &info_ptr, (png_info *)0);
fclose(fpin);
return NULL;
}
if (info_ptr.interlace_type)
{
num_pass = png_set_interlace_handling(&read_ptr);
}
else
{
num_pass = 1;
}
for (pass = 0; pass < num_pass; pass++)
{
for (y = 0; y < info_ptr.height; y++)
{
png_read_rows(&read_ptr, &row_buf, (png_byte **)0, 1); // Read one row of image data
}
}
png_read_end(&read_ptr, &end_info);
x = info_ptr.width;
y = info_ptr.height;
if (info_ptr.bit_depth == 24)
{
rowbytes = (x * 4L); // Make Multiple of 4 bytes (32bit RGB image)
}
else
{
//RS? ByteScanLine = (((x * (unsigned long) info_ptr.bit_depth) + 7L) / 8L); /* Make Multiple of byte */
rowbytes = (((x * (unsigned long) info_ptr.bit_depth) + 7L) / 8L); /* Make Multiple of byte */
}
// info_ptr.color_type =
// PNG_COLOR_TYPE_PALETTE
// PNG_COLOR_TYPE_RGB
// PNG_COLOR_TYPE_GRAY
// PNG_COLOR_TYPE_RGB_ALPHA
// PNG_COLOR_TYPE_GRAY_ALPHA
// Black & White Image
if (info_ptr.bit_depth == 1)
{
BitMap theBits;
theBits.baseAddr = (Ptr) row_buf; // Set up new BitMap
theBits.rowBytes = rowbytes; // width of image
SetRect(&(theBits.bounds), 0, 0, x, y);
//R4L myPic = MakePictFromBW(&theBits);
// create a PicHandle from B&W BitMap
// Cleanup and Exit.
}
else
{
CTabHandle macCtabHandle = nil;// Color Table for 2, 4, 8 bit images
PixMap srcBits;
if (info_ptr.bit_depth >= 2 && info_ptr.bit_depth <= 8)
{
if (info_ptr.valid & PNG_INFO_PLTE)
{
info_ptr.palette;
info_ptr.num_palette;
macCtabHandle = nil; // Get the color table...
}
}
// See: QuickDraw.h
// Setup PixMap data structure:
srcBits.baseAddr = (char *)row_buf;
// ptr to the Pixcell data
// offset to next scan line
srcBits.rowBytes = rowbytes | 0x8000; // pixmap (4, 8, 16 or 24/32bit image)
srcBits.bounds.top = 0; // encloses bitmap
srcBits.bounds.left = 0;
srcBits.bounds.bottom = y;
srcBits.bounds.right = x;
srcBits.pmVersion = 0; // pixMap version number
srcBits.packType = 1; // defines packing format: 1 = direct
srcBits.packSize = 0L; // length of pixel data
srcBits.hRes = 0x480000; // 72dpi fixed point
srcBits.vRes = 0x480000; // vert. resolution (ppi)
srcBits.planeBytes = 0L; // offset to next plane
srcBits.pmTable = macCtabHandle; // color map for this pixMap
srcBits.pmReserved = 0;
if (info_ptr.bit_depth == 24)
{ // RGB data 24bit color, no Color Table
srcBits.pixelType = RGBDirect;
srcBits.pixelSize = 32; // # bits in pixel
srcBits.cmpCount = 3; // # components in pixel (R,G,B)
srcBits.cmpSize = 8; // # bits per component (3 * 8) =
// 24bits + 8bits pad = 32 bits
}
else
{
// Else: 4bit or 8bit color image
srcBits.pixelType = 0;
srcBits.pixelSize = info_ptr.bit_depth; // # bits in pixel
srcBits.cmpCount = 1; // # components in pixel
srcBits.cmpSize = info_ptr.bit_depth; // # bits per component
}
myPic = CreatePICT2( &srcBits, &srcBits.bounds,ditherCopy);
if (srcBits.pmTable)
DisposHandle((Handle) srcBits.pmTable); // Free Color table allocated
}
/*------------ */
/* clean up after the read, and free any memory allocated */
png_read_destroy(&read_ptr, &info_ptr, &end_info);
/* free the structures */
free(row_buf);
fclose(fpin);
SetVol(0, savedVol);
return myPic;
} // End readPNG()
}
return NULL;
}
PicHandle CreatePICT2(PixMap *pixMap,Rect *boundsRect, short mode)
{
OSErr err;
GWorldPtr imageGWorld = NULL;
PixMapHandle phPixMap;
Ptr imageBaseAddr,imagePtr;
long bytesPerRow,gworldBytesPerRow;
CGrafPtr savePort;
GDHandle saveDevice;
short line,imageHeight;
GetGWorld(&savePort, &saveDevice);
err =
NewGWorld(&imageGWorld,pixMap->pixelSize,boundsRect,pixMap->pmTable,NULL,0L)
;
if (err)
return NULL;
SetGWorld(imageGWorld, NULL);
phPixMap = GetGWorldPixMap(imageGWorld);
LockPixels(phPixMap);
imageBaseAddr = GetPixBaseAddr(phPixMap);
bytesPerRow = pixMap->rowBytes & 0x3fff;
//Bytes per Row
gworldBytesPerRow = (**phPixMap).rowBytes & 0x3fff;
imagePtr = pixMap->baseAddr;
imageHeight = boundsRect->bottom - boundsRect->top;
for (line = boundsRect->top; line < boundsRect->bottom;line++)
{
BlockMove(imagePtr,imageBaseAddr,bytesPerRow);
imageBaseAddr = imageBaseAddr + gworldBytesPerRow;
imagePtr = imagePtr + bytesPerRow;
}
SetGWorld(savePort, saveDevice);
err = DumpPixMap(phPixMap); //Debug Purposes just
output the pixmap to a window the size of the pixmap
UnlockPixels(phPixMap);
DisposeGWorld(imageGWorld);
return (PicHandle)NULL;
}
OSErr DumpPixMap(PixMapHandle aPixMap)
{
WindowPtr myWind;
Rect windowRect,pixRect;
long finalTick;
RGBColor white = {0xFFFF,0xFFFF,0xFFFF};
RGBColor black = {0x0000,0x0000,0x0000};
if (aPixMap == NULL)
{
DebugStr("\pNull Pixmap Handle in DumpPixMap");
return memFullErr;
}
HLock((Handle)aPixMap);
pixRect = (**aPixMap).bounds;
centerRectOnMainScreen(&pixRect,&pixRect);
InsetRect(&pixRect,2,2);
myWind = NewWindow(NULL, &pixRect, "\p Pixmap", TRUE, documentProc,
(WindowPtr)-1, FALSE, NULL);
if (myWind != nil)
{
ShowWindow(myWind);
}
SelectWindow(myWind); // activate the "Shell Window"
windowRect = myWind->portRect;
InsetRect(&windowRect,1,1);
RGBForeColor(&black);
RGBBackColor(&white);
CopyBits(*(BitMap **)aPixMap,
&(myWind)->portBits,
&windowRect,
&windowRect,
srcCopy, NULL);
BeginUpdate(myWind);
EndUpdate(myWind);
Delay(60,&finalTick);
Debugger();
DisposeWindow(myWind);
HUnlock((Handle)aPixMap);
return noErr;
}
void centerRectOnMainScreen(Rect *theRect,Rect *resultRect)
{
short var1,var2;
Rect centerRect;
GDHandle mainDevice;
mainDevice = GetMainDevice();
centerRect = (**mainDevice).gdRect;
*resultRect = *theRect;
var1 = theRect->right - theRect->left;
var2 = centerRect.right - centerRect.left;
if (var1 < var2)
{
RECT_LEFT(*resultRect) = RECT_MIDX(centerRect) - (var1 >> 1);
RECT_RIGHT(*resultRect) = RECT_LEFT(*resultRect) + var1;
}
var1 = theRect->bottom - theRect->top;
var2 = centerRect.bottom - centerRect.top;
if (var1 < var2)
{
RECT_TOP(*resultRect) = RECT_MIDY(centerRect) - (var1 >> 1);
RECT_BOTTOM(*resultRect) = RECT_TOP(*resultRect) + var1;
}
}
,
>
>sorry for the problems .. I did start to write ReadPNG.c (and never got
>back to it), I did think I have included it in the archive file...
>
>I was planning on finishing it and getting it to work for my external
>translators (XTND, MacEasy Open, etc...).
>
>I don't know when I will have time to finish it. What problems have you
>fixed and what problems are you having?
>
>If my memory is correct, I was going to manually create an offscreen pixmap
>and color table and then call a special routine for creating PICT handles
>that is portable and does not require color quickdraw (you could used
>OpenPicture()... etc).
>
>currently no update ... but when I do get to it will send you a note. Let
>me know If you get it working, and I will include it as an update.
>
>
>> I'm trying to get a simple demo up and running that reads and
>>displays a PNG image using your mac CW port. I tried compiling the ReadPNG
>>file, but there are a host of problems. I've tried to fix the obvious ones,
>>but am having problems getting the image to display properly. Did you write
>>ReadPNG.c? Is there an updated version?
>>
>>Roger Smith
>
><<<<->>>>|
> Mark Fleming, http://ccsmacinfo.ccs.queensu.ca/Mark/
> Stauffer Library, Room 011c, Computing & Comm. Services,
> Queen's University at Kingston, Ontario, Canada, K7L 3N6
> MarkF@post.QueensU.CA, Tel:1-613-545-2039 Fax:613-545-6798